package com.example.security.aspect;

import com.example.security.annotation.DataScope;
import com.example.security.common.BaseQuery;
import com.example.security.entity.SysUser;
import com.example.security.service.OrgService;
import com.example.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 数据权限过滤切面
 * 实现数据权限的动态过滤
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class DataScopeAspect {

    private final OrgService orgService;

    /**
     * 数据权限过滤处理
     * 在方法执行前注入数据权限过滤条件
     */
    @Before("@annotation(com.example.security.annotation.DataScope)")
    public void doBefore(JoinPoint point) {
        handleDataScope(point);
    }

    /**
     * 处理数据权限
     * 1. 获取当前用户权限范围
     * 2. 生成权限过滤SQL
     * 3. 注入到查询参数中
     */
    private void handleDataScope(JoinPoint point) {
        try {
            // 获取当前用户
            SysUser currentUser = SecurityUtils.getCurrentUser();
            if (currentUser == null || SecurityUtils.isAdmin(currentUser)) {
                return;
            }

            // 获取数据权限配置
            MethodSignature signature = (MethodSignature) point.getSignature();
            DataScope dataScope = signature.getMethod().getAnnotation(DataScope.class);
            if (dataScope == null) {
                return;
            }

            // 生成数据权限SQL
            String dataScopeSql = getDataScopeSql(dataScope, currentUser);

            // 注入到查询参数
            Object params = point.getArgs()[0];
            if (params instanceof BaseQuery) {
                ((BaseQuery) params).setDataScopeSql(dataScopeSql);
            }
        } catch (Exception e) {
            log.error("数据权限处理异常", e);
        }
    }

    /**
     * 生成数据权限SQL
     * 根据用户权限范围生成对应的SQL过滤条件
     */
    private String getDataScopeSql(DataScope dataScope, SysUser user) {
        StringBuilder sql = new StringBuilder();
        
        // 获取机构ID列表
        List<Long> orgIds = orgService.getSubOrgIds(user.getOrgId());
        if (dataScope.includeSelf()) {
            orgIds.add(user.getOrgId());
        }

        // 拼接SQL条件
        if (!orgIds.isEmpty()) {
            sql.append(" AND ").append(dataScope.orgAlias())
               .append(".org_id IN (")
               .append(String.join(",", orgIds.stream()
                   .map(String::valueOf).toArray(String[]::new)))
               .append(") ");
        }

        return sql.toString();
    }
} 